/*
 * sbus.c
 *
 *  Created on: 2017年3月14日
 *      Author: chen
 */


/* Includes ------------------------------------------------------------------*/
#include "sbus.h"
#include "usart.h"
#include <string.h>

/* Definitions ---------------------------------------------------------------*/
#define UART_BUFFER_SIZE        (50U)
#define SBUS_FRAME_SIZE         (25U)

#define SBUS_FAILSAFE_INACTIVE  (0U)
#define SBUS_FAILSAFE_ACTIVE    (1U)
#define SBUS_STARTBYTE          (0x0F)
#define SBUS_ENDBYTE            (0x00)

/* Variables -----------------------------------------------------------------*/
static sbusFSM_t FSM;

uint8_t g_Buffer[UART_BUFFER_SIZE];
uint8_t frame[SBUS_FRAME_SIZE];

/* Codes ---------------------------------------------------------------------*/
void Sbus_UpdateRC(sbusChannel_t *sbus)
{
  /* 检测是否有传入参数 */
  if (sbus == NULL)
    return;

  if (frame[0] == SBUS_STARTBYTE && frame[SBUS_FRAME_SIZE - 1] == SBUS_ENDBYTE)
  {
    sbus->ch[0] = ((frame[1] | frame[2] << 8) & 0x07FF);
    sbus->ch[1] = ((frame[2] >> 3 | frame[3] << 5) & 0x07FF);
    sbus->ch[2] = ((frame[3] >> 6 | frame[4] << 2 | frame[5] << 10) & 0x07FF);
    sbus->ch[3] = ((frame[5] >> 1 | frame[6] << 7) & 0x07FF);
    sbus->ch[4] = ((frame[6] >> 4 | frame[7] << 4) & 0x07FF);
    sbus->ch[5] = ((frame[7] >> 7 | frame[8] << 1 | frame[9] << 9) & 0x07FF);
    sbus->ch[6] = ((frame[9] >> 2 | frame[10] << 6) & 0x07FF);
    sbus->ch[7] = ((frame[10] >> 5 | frame[11] << 3) & 0x07FF);
    sbus->ch[8] = ((frame[12] | frame[13] << 8) & 0x07FF);
    sbus->ch[9] = ((frame[13] >> 3 | frame[14] << 5) & 0x07FF);
    sbus->ch[10] = ((frame[14] >> 6 | frame[15] << 2 | frame[16] << 10) & 0x07FF);
    sbus->ch[11] = ((frame[16] >> 1 | frame[17] << 7) & 0x07FF);
    sbus->ch[12] = ((frame[17] >> 4 | frame[18] << 4) & 0x07FF);
    sbus->ch[13] = ((frame[18] >> 7 | frame[19] << 1 | frame[20] << 9) & 0x07FF);
    sbus->ch[14] = ((frame[20] >> 2 | frame[21] << 6) & 0x07FF);
    sbus->ch[15] = ((frame[21] >> 5 | frame[22] << 3) & 0x07FF);

    sbus->ch[16] = ((frame[23]) & 0x0001) ? 2047 : 0;
    sbus->ch[17] = ((frame[23] >> 1) & 0x0001) ? 2047 : 0;

    if ((frame[23] >> 3) & 0x0001)
      sbus->failSafe = SBUS_FAILSAFE_ACTIVE;
    else
      sbus->failSafe = SBUS_FAILSAFE_INACTIVE;

    if ((frame[23] >> 2) & 0x0001)
      sbus->lostFrames++;
  }
}

int Sbus_GetFrame(void)
{
  if (FSM == IDLE)  //如果为空闲状态则开始检测同步信号
  {
    FSM = SYNC;
    HAL_UART_Receive_IT(&huart1, &g_Buffer[0], 1);
  }
  else if (FSM == FAILED) //失败处理
  {
    FSM = IDLE;
  }
  else if (FSM == FINISH) //接收到完整数据包
  {
    memcpy(frame, g_Buffer, SBUS_FRAME_SIZE);
    FSM = IDLE;
    return 0;
  }

  return -1;
}

/**
  * @brief  Rx Transfer completed callbacks.
  * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  
  if (FSM == SYNC)
  {
    if (g_Buffer[0] == SBUS_STARTBYTE)
    {
      FSM = RECEIVE;
      HAL_UART_Receive_IT(&huart1, &g_Buffer[1], SBUS_FRAME_SIZE - 1);
    }
    else
      FSM = FAILED;
  }
  else if (FSM == RECEIVE)
  {
    if (g_Buffer[SBUS_FRAME_SIZE - 1] == SBUS_ENDBYTE)
      FSM = FINISH;
    else
      FSM = FAILED;
  }
}
